using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace IppServer.Host.Discovery
{
    /// <summary>
    /// mDNS 服务发现管理器
    /// 用于在局域网中自动发现IPP打印机
    /// </summary>
    internal sealed class MdnsServiceDiscovery : IDisposable
    {
        private const string BonjourServiceName = "Bonjour Service";
        private const int MdnsPort = 5353;
        private readonly Action<string> _logCallback;
        private readonly List<MdnsServiceRegistration> _registeredServices = new List<MdnsServiceRegistration>();
        private bool _isDisposed;
        private bool _isRunning;

        public MdnsServiceDiscovery(Action<string> logCallback = null)
        {
            _logCallback = logCallback;
        }

        /// <summary>
        /// 检查Bonjour服务是否可用
        /// </summary>
        public static bool IsBonjourAvailable()
        {
            try
            {
                // 方法1：检查是否有Bonjour相关的进程（更快，避免GetServices的阻塞）
                try
                {
                    var processes = Process.GetProcesses();
                    if (processes.Any(p => 
                        p.ProcessName.IndexOf("mDNSResponder", StringComparison.OrdinalIgnoreCase) >= 0 ||
                        p.ProcessName.IndexOf("Bonjour", StringComparison.OrdinalIgnoreCase) >= 0))
                    {
                        return true;
                    }
                }
                catch
                {
                    // 忽略进程检查错误
                }

                // 方法2：检查Bonjour服务是否运行（可能较慢，作为备选）
                try
                {
                    var services = ServiceController.GetServices();
                    var bonjourService = services.FirstOrDefault(s => 
                        s.ServiceName.IndexOf("Bonjour", StringComparison.OrdinalIgnoreCase) >= 0 ||
                        s.DisplayName.IndexOf("Bonjour", StringComparison.OrdinalIgnoreCase) >= 0);
                    
                    if (bonjourService != null)
                    {
                        try
                        {
                            bonjourService.Refresh();
                            return bonjourService.Status == ServiceControllerStatus.Running;
                        }
                        catch
                        {
                            // 如果无法访问服务状态，尝试其他方法
                        }
                    }
                }
                catch
                {
                    // 忽略服务检查错误
                }

                // 方法3：尝试绑定mDNS端口（UDP 5353），如果失败可能说明已有服务在运行
                try
                {
                    using (var testSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
                    {
                        testSocket.Bind(new IPEndPoint(IPAddress.Any, MdnsPort));
                        testSocket.Close();
                        // 如果能绑定，说明没有其他服务在使用，可能Bonjour不可用
                        return false;
                    }
                }
                catch
                {
                    // 如果绑定失败，可能端口被占用，说明可能有Bonjour服务
                    return true;
                }
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 启动mDNS服务发现
        /// </summary>
        public bool Start(List<PrinterServiceInfo> printerServices, int port, Action<string> logCallback = null)
        {
            if (_isRunning)
            {
                return true;
            }

            // 检查Bonjour环境（但不强制要求，会尝试原生mDNS作为备选）
            var hasBonjour = IsBonjourAvailable();
            if (!hasBonjour)
            {
                var logMsg = logCallback ?? _logCallback;
                logMsg?.Invoke("提示：未检测到Bonjour环境，将尝试使用原生mDNS协议。");
                logMsg?.Invoke("  Windows 7用户建议安装Apple Bonjour服务以获得更好的兼容性。");
                logMsg?.Invoke("  Windows 10/11通常已内置mDNS支持，原生协议也可工作。");
            }

            // 确保防火墙规则允许mDNS（UDP 5353端口）
            EnsureMdnsFirewallRule(logCallback ?? _logCallback);

            try
            {
                // 注册每个打印机队列的mDNS服务
                foreach (var printerService in printerServices)
                {
                    RegisterService(printerService, port, logCallback ?? _logCallback, hasBonjour);
                }

                _isRunning = true;
                (logCallback ?? _logCallback)?.Invoke($"mDNS服务发现已启动，已注册 {_registeredServices.Count} 个打印机服务。");
                return true;
            }
            catch (Exception ex)
            {
                var logMsg = logCallback ?? _logCallback;
                logMsg?.Invoke($"启动mDNS服务发现失败：{ex.Message}");
                logMsg?.Invoke("  核心打印功能不受影响，客户端可通过手动输入地址添加打印机。");
                return false;
            }
        }

        /// <summary>
        /// 停止mDNS服务发现
        /// </summary>
        public void Stop()
        {
            if (!_isRunning)
            {
                return;
            }

            try
            {
                // 注销所有已注册的服务
                foreach (var service in _registeredServices.ToList())
                {
                    UnregisterService(service);
                }

                _registeredServices.Clear();
                _isRunning = false;
                _logCallback?.Invoke("mDNS服务发现已停止。");
            }
            catch (Exception ex)
            {
                _logCallback?.Invoke($"停止mDNS服务发现时发生错误：{ex.Message}");
            }
        }

        /// <summary>
        /// 注册单个打印机服务
        /// </summary>
        private void RegisterService(PrinterServiceInfo serviceInfo, int port, Action<string> logCallback, bool hasBonjour)
        {
            try
            {
                // 检查是否已经注册了相同名称的服务
                var sanitizedServiceName = SanitizeServiceName(serviceInfo.PrinterName);
                var existingRegistration = _registeredServices.FirstOrDefault(r => 
                    r.FullServiceName?.Contains(sanitizedServiceName) == true ||
                    r.QueueName == serviceInfo.QueueName);
                
                if (existingRegistration != null)
                {
                    logCallback?.Invoke($"mDNS服务已存在，跳过重复注册：{serviceInfo.ServiceName}");
                    return;
                }
                
                var registration = new MdnsServiceRegistration
                {
                    ServiceName = serviceInfo.ServiceName,
                    QueueName = serviceInfo.QueueName,
                    Port = port,
                    PrinterName = serviceInfo.PrinterName,
                    ProcessId = -1 // 未启动
                };

                // 方法1：优先尝试使用dns-sd命令行工具（如果Bonjour已安装且可用）
                if (hasBonjour && TryRegisterUsingDnsSd(registration, port, logCallback))
                {
                    _registeredServices.Add(registration);
                    logCallback?.Invoke($"已注册mDNS服务（dns-sd）：{serviceInfo.ServiceName} ({serviceInfo.QueueName})");
                    return;
                }

                // 方法2：实现原生mDNS协议（UDP多播）- 作为备选方案
                if (TryRegisterUsingNativeMdns(registration, port, logCallback))
                {
                    _registeredServices.Add(registration);
                    logCallback?.Invoke($"已注册mDNS服务（原生协议）：{serviceInfo.ServiceName} ({serviceInfo.QueueName})");
                    return;
                }

                // 如果两种方法都失败
                logCallback?.Invoke($"警告：无法注册mDNS服务：{serviceInfo.ServiceName}，客户端可能无法自动发现此打印机");
            }
            catch (Exception ex)
            {
                logCallback?.Invoke($"注册mDNS服务失败：{serviceInfo.ServiceName}，错误：{ex.Message}");
            }
        }

        /// <summary>
        /// 尝试使用dns-sd命令行工具注册服务（需要Bonjour SDK）
        /// </summary>
        private bool TryRegisterUsingDnsSd(MdnsServiceRegistration registration, int port, Action<string> logCallback)
        {
            try
            {
                // 查找dns-sd.exe的位置（通常在Bonjour SDK或系统目录中）
                var dnsSdPaths = new[]
                {
                    @"C:\Program Files\Bonjour\mdnsNSP.dll", // 通过检测DLL判断
                    @"dns-sd.exe", // PATH环境变量中
                    @"C:\Program Files\Bonjour\dns-sd.exe"
                };

                string dnsSdExe = null;
                foreach (var path in dnsSdPaths)
                {
                    if (path.EndsWith(".exe"))
                    {
                        if (System.IO.File.Exists(path))
                        {
                            dnsSdExe = path;
                            break;
                        }
                        // 尝试从PATH查找
                        try
                        {
                            var whichResult = RunCommand("where", $"dns-sd.exe");
                            if (!string.IsNullOrWhiteSpace(whichResult) && System.IO.File.Exists(whichResult.Trim()))
                            {
                                dnsSdExe = whichResult.Trim();
                                break;
                            }
                        }
                        catch { }
                    }
                    else if (path.EndsWith(".dll") && System.IO.File.Exists(path))
                    {
                        // 如果找到Bonjour DLL，尝试在相同目录查找dns-sd.exe
                        var dir = System.IO.Path.GetDirectoryName(path);
                        var exePath = System.IO.Path.Combine(dir, "dns-sd.exe");
                        if (System.IO.File.Exists(exePath))
                        {
                            dnsSdExe = exePath;
                            break;
                        }
                    }
                }

                if (string.IsNullOrEmpty(dnsSdExe))
                {
                    return false; // 未找到dns-sd工具
                }

                // 构建服务名称（符合IPP规范）
                // 格式：Printer Name._ipp._tcp.local
                var serviceName = SanitizeServiceName(registration.PrinterName);
                var fullServiceName = $"{serviceName}._ipp._tcp.local";
                registration.FullServiceName = fullServiceName;
                
                // 获取主机名（用于adminurl）
                // 关键修复：优先使用IP地址，确保Windows使用正确的端口格式
                var localIp = GetLocalIpAddress();
                var hostnameForUrl = !string.IsNullOrEmpty(localIp) ? localIp : "127.0.0.1";
                
                // 构建完整的TXT记录（包含所有IPP打印机信息）
                // dns-sd的TXT记录格式：每个键值对作为独立的字符串，用引号包裹
                var txtRecordParts = BuildTxtRecordParts(registration.PrinterName, registration.QueueName, port, hostnameForUrl);
                var txtRecordArgs = string.Join(" ", txtRecordParts.Select(part => $"\"{EscapeTxtValue(part)}\""));
                
                // 使用dns-sd注册服务（在后台运行）
                // dns-sd -R "Service Name" _ipp._tcp local 631 "txtvers=1" "rp=..." "ty=..." ...
                // 注意：域应该是 "local" 而不是 "."，这样才能在 .local 域中正确注册
                var arguments = $"-R \"{serviceName}\" _ipp._tcp local {port} {txtRecordArgs}";

                var processInfo = new ProcessStartInfo
                {
                    FileName = dnsSdExe,
                    Arguments = arguments,
                    UseShellExecute = false,
                    CreateNoWindow = true,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    StandardOutputEncoding = Encoding.UTF8
                };

                var process = Process.Start(processInfo);
                if (process != null && !process.HasExited)
                {
                    registration.ProcessId = process.Id;
                    registration.RegistrationMethod = "dns-sd";
                    registration.FullServiceName = fullServiceName;
                    
                    // dns-sd会持续运行，所以我们保持进程引用
                    // 异步等待注册确认（避免阻塞）
                    Task.Run(() =>
                    {
                        try
                        {
                            System.Threading.Thread.Sleep(500); // 短暂等待让进程启动
                            
                            if (!process.HasExited)
                            {
                                // 异步读取输出和错误信息
                                var output = process.StandardOutput.ReadToEnd();
                                var error = process.StandardError.ReadToEnd();
                                
                                // dns-sd -R 命令成功时通常会输出 "Registered" 或类似的确认信息
                                if (!string.IsNullOrWhiteSpace(error) && 
                                    !error.Contains("Registering") && 
                                    !error.Contains("Registered") &&
                                    !string.IsNullOrWhiteSpace(error.Trim()))
                                {
                                    logCallback?.Invoke($"dns-sd注册可能有警告：{error.Trim()}");
                                }
                                
                                logCallback?.Invoke($"使用dns-sd注册mDNS服务：{fullServiceName} (进程ID: {process.Id})");
                                // logCallback?.Invoke($"  注册命令：dns-sd {arguments}");
                            }
                            else
                            {
                                // 进程已退出，可能是注册失败
                                var output = process.StandardOutput.ReadToEnd();
                                var error = process.StandardError.ReadToEnd();
                                var errorMsg = !string.IsNullOrWhiteSpace(error) ? error : output;
                                logCallback?.Invoke($"dns-sd注册失败（进程已退出）：{errorMsg.Trim()}");
                            }
                        }
                        catch
                        {
                            // 忽略异步检查中的错误
                        }
                    });
                    
                    // 立即返回成功，不等待注册确认（避免阻塞UI）
                    logCallback?.Invoke($"正在注册mDNS服务（dns-sd）：{fullServiceName}");
                    return true;
                }
                
                return false;
            }
            catch (Exception ex)
            {
                logCallback?.Invoke($"使用dns-sd注册失败：{ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 尝试使用原生mDNS协议注册服务（UDP多播）
        /// </summary>
        private bool TryRegisterUsingNativeMdns(MdnsServiceRegistration registration, int port, Action<string> logCallback)
        {
            try
            {
                // 获取主机名（用于adminurl）
                // 关键修复：优先使用IP地址，确保Windows使用正确的端口格式
                var localIp = GetLocalIpAddress();
                var hostnameForUrl = !string.IsNullOrEmpty(localIp) ? localIp : "127.0.0.1";
                
                // 构建完整的TXT记录
                var txtRecord = BuildTxtRecord(registration.PrinterName, registration.QueueName, port, hostnameForUrl);
                
                // 使用原生mDNS发布器
                var publisher = new NativeMdnsPublisher(
                    SanitizeServiceName(registration.PrinterName),
                    registration.PrinterName,
                    registration.QueueName,
                    port,
                    txtRecord
                );

                if (publisher.Start())
                {
                    registration.NativePublisher = publisher;
                    registration.RegistrationMethod = "native";
                    registration.FullServiceName = $"{SanitizeServiceName(registration.PrinterName)}._ipp._tcp.local";
                    logCallback?.Invoke($"使用原生mDNS协议注册服务：{registration.FullServiceName}");
                    return true;
                }
                else
                {
                    publisher.Dispose();
                    logCallback?.Invoke("原生mDNS注册失败：无法绑定UDP端口或加入多播组");
                    return false;
                }
            }
            catch (Exception ex)
            {
                logCallback?.Invoke($"原生mDNS注册失败：{ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 注销单个服务
        /// </summary>
        private void UnregisterService(MdnsServiceRegistration registration)
        {
            try
            {
                if (registration.ProcessId > 0)
                {
                    // 如果使用dns-sd注册，需要终止对应的进程
                    try
                    {
                        var process = Process.GetProcessById(registration.ProcessId);
                        if (process != null && !process.HasExited)
                        {
                            process.Kill();
                            process.WaitForExit(2000);
                            _logCallback?.Invoke($"已注销mDNS服务（终止进程 {registration.ProcessId}）：{registration.ServiceName}");
                        }
                    }
                    catch (ArgumentException)
                    {
                        // 进程已不存在，忽略
                    }
                    catch (Exception ex)
                    {
                        _logCallback?.Invoke($"注销mDNS服务时无法终止进程：{ex.Message}");
                    }
                }
                else if (registration.NativePublisher != null)
                {
                    // 如果使用原生mDNS，停止发布器
                    try
                    {
                        registration.NativePublisher.Stop();
                        registration.NativePublisher.Dispose();
                        _logCallback?.Invoke($"已注销原生mDNS服务：{registration.ServiceName}");
                    }
                    catch (Exception ex)
                    {
                        _logCallback?.Invoke($"注销原生mDNS服务时发生错误：{ex.Message}");
                    }
                }
                else
                {
                    _logCallback?.Invoke($"已注销mDNS服务：{registration.ServiceName}");
                }
            }
            catch (Exception ex)
            {
                _logCallback?.Invoke($"注销mDNS服务失败：{registration.ServiceName}，错误：{ex.Message}");
            }
        }

        /// <summary>
        /// 构建完整的mDNS TXT记录（符合IPP规范）
        /// 返回用空格连接的字符串，用于dns-sd命令
        /// </summary>
        private static string BuildTxtRecord(string printerName, string queueName, int port, string hostname = null)
        {
            var txtParts = BuildTxtRecordParts(printerName, queueName, port, hostname);
            return string.Join(" ", txtParts);
        }
        
        /// <summary>
        /// 构建mDNS TXT记录的键值对列表
        /// </summary>
        private static List<string> BuildTxtRecordParts(string printerName, string queueName, int port, string hostname = null)
        {
            var txtParts = new List<string>();
            
            // txtvers=1 - TXT记录版本号（必需）
            txtParts.Add("txtvers=1");
            
            // rp=printers/{queueName} - 资源路径（必需，IPP规范）
            // 这个路径必须与实际的IPP端点路径匹配
            txtParts.Add($"rp=printers/{queueName}");
            
            // ty={printerName} - 打印机类型/名称（必需）
            // 注意：如果printerName包含特殊字符，需要正确转义或处理
            txtParts.Add($"ty={printerName}");
            
            // pdl=... - 支持的页面描述语言（重要）
            // 确保包含Windows支持的格式
            txtParts.Add("pdl=image/urf,application/octet-stream,image/pwg-raster");
            
            // product=({printerName}) - 产品型号
            txtParts.Add($"product=({printerName})");
            
            // UUID=... - 打印机唯一标识符（基于打印机名称生成稳定的UUID）
            var uuid = GenerateStableUuid(printerName, queueName);
            txtParts.Add($"UUID={uuid}");
            
            // kind=document,envelope - 打印机类型
            txtParts.Add("kind=document,envelope");
            
            // qtotal=1 - 队列总数
            txtParts.Add("qtotal=1");
            
            // 关键修复：移除 print_wfds 字段，避免Windows使用WSD协议
            // print_wfds=T 会导致Windows创建WSD端口（WSD-xxxxx格式），而不是IPP端口（http://IP:PORT格式）
            // 我们不添加这个字段，让Windows使用标准的IPP协议
            
            // URF=... - AirPrint/URF格式支持（Windows可能需要）
            txtParts.Add("URF=CP1,IS1,OB10,PQ3-4-5,RS600,W8,V1.4");
            
            // mopria-certified=2.0 - Mopria认证（可选，但有助于兼容性）
            txtParts.Add("mopria-certified=2.0");
            
            // usb_MFG=... / usb_MDL=... - USB制造商和型号信息（Windows用于匹配驱动）
            // 同时添加MFG和MDL字段（不带usb_前缀），某些系统可能需要这个格式
            var mfg = ExtractManufacturer(printerName);
            var mdl = ExtractModel(printerName);
            if (!string.IsNullOrEmpty(mfg))
            {
                txtParts.Add($"usb_MFG={mfg}");
                txtParts.Add($"MFG={mfg}"); // 添加不带前缀的版本
            }
            if (!string.IsNullOrEmpty(mdl))
            {
                txtParts.Add($"usb_MDL={mdl}");
                txtParts.Add($"MDL={mdl}"); // 添加不带前缀的版本
            }
            
            // adminurl=... - 管理URL（关键修复：使用IP地址格式，确保Windows使用正确的端口格式）
            // 优先使用IP地址，这样Windows会使用 http://IP:PORT/printers/queue 格式，而不是WSD格式
            string adminUrlHostname;
            if (!string.IsNullOrEmpty(hostname) && System.Net.IPAddress.TryParse(hostname, out _))
            {
                // 如果hostname是IP地址，直接使用
                adminUrlHostname = hostname;
            }
            else
            {
                // 否则尝试获取本地IP地址
                var localIp = GetLocalIpAddress();
                if (!string.IsNullOrEmpty(localIp))
                {
                    adminUrlHostname = localIp;
                }
                else if (!string.IsNullOrEmpty(hostname))
                {
                    // 如果无法获取IP，使用提供的hostname
                    adminUrlHostname = hostname;
                }
                else
                {
                    // 最后回退到localhost
                    adminUrlHostname = "127.0.0.1";
                }
            }
            // 使用IP地址格式的URL，确保Windows使用正确的端口格式
            txtParts.Add($"adminurl=http://{adminUrlHostname}:{port}/printers/{queueName}");
            
            // Color=F - 不支持彩色（默认）
            txtParts.Add("Color=F");
            
            // Duplex=F - 不支持双面打印（默认）
            txtParts.Add("Duplex=F");
            
            // Transparent=T - 支持透明
            txtParts.Add("Transparent=T");
            
            // Binary=T - 支持二进制
            txtParts.Add("Binary=T");
            
            // note= - 备注（可为空）
            txtParts.Add("note=");
            
            return txtParts;
        }
        
        /// <summary>
        /// 生成稳定的UUID（基于打印机名称和队列名称）
        /// </summary>
        private static string GenerateStableUuid(string printerName, string queueName)
        {
            // 使用打印机名称和队列名称生成稳定的UUID
            // 这样同一台打印机的UUID总是相同的
            var input = $"{printerName}:{queueName}";
            var bytes = Encoding.UTF8.GetBytes(input);
            
            // 使用MD5哈希生成UUID v3风格的UUID
            using (var md5 = System.Security.Cryptography.MD5.Create())
            {
                var hash = md5.ComputeHash(bytes);
                
                // 将MD5哈希转换为UUID格式 (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
                // 设置版本位（第13个字节的高4位为3）和变体位（第17个字节的高2位为10）
                hash[6] = (byte)((hash[6] & 0x0F) | 0x30); // 版本3
                hash[8] = (byte)((hash[8] & 0x3F) | 0x80); // 变体
                
                return $"{BitConverter.ToString(hash, 0, 4).Replace("-", "").ToLower()}-" +
                       $"{BitConverter.ToString(hash, 4, 2).Replace("-", "").ToLower()}-" +
                       $"{BitConverter.ToString(hash, 6, 2).Replace("-", "").ToLower()}-" +
                       $"{BitConverter.ToString(hash, 8, 2).Replace("-", "").ToLower()}-" +
                       $"{BitConverter.ToString(hash, 10, 6).Replace("-", "").ToLower()}";
            }
        }
        
        /// <summary>
        /// 从打印机名称中提取制造商（改进版，更准确匹配Windows驱动）
        /// </summary>
        private static string ExtractManufacturer(string printerName)
        {
            if (string.IsNullOrWhiteSpace(printerName))
                return "Generic";
            
            var upperName = printerName.ToUpperInvariant();
            
            // 常见的打印机制造商（按常见程度排序，优先匹配）
            var manufacturers = new[]
            {
                "HP", "Hewlett-Packard", "Hewlett Packard",
                "Canon",
                "Epson",
                "Brother",
                "Pantum",
                "Xerox",
                "Lexmark",
                "Samsung",
                "Ricoh",
                "Konica", "Konica Minolta",
                "Minolta",
                "Kyocera",
                "OKI", "Oki",
                "Sharp",
                "Toshiba",
                "Fuji Xerox",
                "Dell"
            };
            
            // 优先匹配完整名称
            foreach (var mfg in manufacturers)
            {
                if (upperName.Contains(mfg.ToUpperInvariant()))
                {
                    // 返回标准化的制造商名称（使用最常见的格式）
                    if (mfg.Contains("Hewlett"))
                        return "HP";
                    if (mfg.Contains("Konica"))
                        return "Konica Minolta";
                    return mfg.Split(' ')[0]; // 取第一个单词作为标准名称
                }
            }
            
            // 如果未找到，尝试提取第一个单词作为制造商
            var parts = printerName.Split(new[] { ' ', '-', '_' }, StringSplitOptions.RemoveEmptyEntries);
            if (parts.Length > 0 && parts[0].Length > 0)
            {
                return parts[0];
            }
            
            return "Generic";
        }
        
        /// <summary>
        /// 从打印机名称中提取型号（改进版，更准确匹配Windows驱动）
        /// </summary>
        private static string ExtractModel(string printerName)
        {
            if (string.IsNullOrWhiteSpace(printerName))
                return "IPP Printer";
            
            // 尝试提取型号（通常是包含数字的部分）
            var parts = printerName.Split(new[] { ' ', '-', '_', '(', ')' }, StringSplitOptions.RemoveEmptyEntries);
            
            // 优先查找包含数字的部分作为型号（通常是型号）
            foreach (var part in parts)
            {
                if (part.Length > 0 && char.IsDigit(part[0]))
                {
                    // 提取完整的型号字符串（可能包含字母和数字，如 "HP1018", "LaserJet 1020"）
                    return part;
                }
            }
            
            // 如果未找到以数字开头的部分，查找包含数字的部分
            foreach (var part in parts)
            {
                if (part.Length > 0 && part.Any(char.IsDigit))
                {
                    return part;
                }
            }
            
            // 如果仍未找到，尝试组合多个部分（跳过第一个，因为通常是制造商）
            if (parts.Length > 1)
            {
                var modelParts = parts.Skip(1).Where(p => !string.IsNullOrWhiteSpace(p)).Take(2);
                var model = string.Join(" ", modelParts);
                if (!string.IsNullOrWhiteSpace(model))
                {
                    return model;
                }
            }
            
            // 最后回退：使用整个名称
            return printerName;
        }

        /// <summary>
        /// 转义TXT记录值中的特殊字符（用于dns-sd命令行）
        /// </summary>
        private static string EscapeTxtValue(string value)
        {
            if (string.IsNullOrEmpty(value))
                return value;
            
            // dns-sd在命令行中，引号内的内容会被直接使用
            // 如果值中包含引号，需要转义，但对于命令行参数，我们已经在外面加了引号
            // 这里主要是处理可能的问题字符
            // 实际上，对于大多数情况，直接返回即可，因为外层已有引号保护
            return value;
        }

        /// <summary>
        /// 清理服务名称，使其符合DNS规范
        /// </summary>
        private static string SanitizeServiceName(string name)
        {
            if (string.IsNullOrWhiteSpace(name))
            {
                return "IPP-Printer";
            }

            // 移除或替换不符合DNS规范的字符
            var sanitized = name
                .Replace(" ", "-")
                .Replace("(", "")
                .Replace(")", "")
                .Replace(".", "-")
                .Replace(",", "")
                .Replace("/", "-")
                .Replace("\\", "-")
                .Replace(":", "-")
                .Replace(";", "-")
                .Replace("\"", "")
                .Replace("'", "");

            // 限制长度
            if (sanitized.Length > 63)
            {
                sanitized = sanitized.Substring(0, 63);
            }

            return sanitized;
        }

        /// <summary>
        /// 获取第一个可用的本地IP地址（IPv4）
        /// </summary>
        private static string GetLocalIpAddress()
        {
            try
            {
                var addresses = Dns.GetHostEntry(Dns.GetHostName()).AddressList;
                var ipv4Address = addresses.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork && !IPAddress.IsLoopback(ip));
                return ipv4Address?.ToString() ?? string.Empty;
            }
            catch
            {
                return string.Empty;
            }
        }

        /// <summary>
        /// 运行命令并返回输出
        /// </summary>
        private static string RunCommand(string fileName, string arguments)
        {
            try
            {
                var processInfo = new ProcessStartInfo
                {
                    FileName = fileName,
                    Arguments = arguments,
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    CreateNoWindow = true,
                    StandardOutputEncoding = Encoding.UTF8
                };

                using (var process = Process.Start(processInfo))
                {
                    if (process == null)
                    {
                        return null;
                    }

                    var output = process.StandardOutput.ReadToEnd();
                    process.WaitForExit(3000);
                    return output;
                }
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// 确保防火墙规则允许mDNS（UDP 5353端口）
        /// </summary>
        private static void EnsureMdnsFirewallRule(Action<string> logCallback)
        {
            try
            {
                // 检查是否有管理员权限
                if (!IsRunningAsAdministrator())
                {
                    logCallback?.Invoke("提示：未以管理员权限运行，无法自动添加mDNS防火墙规则（UDP 5353端口）。");
                    return;
                }

                // 检查规则是否已存在
                var ruleName = "IPP Server - mDNS (UDP 5353)";
                if (FirewallRuleExists(ruleName))
                {
                    logCallback?.Invoke($"mDNS防火墙规则 '{ruleName}' 已存在，跳过添加。");
                    return;
                }

                // 添加UDP 5353端口的防火墙规则（mDNS使用）
                var command = $"advfirewall firewall add rule name=\"{ruleName}\" dir=in action=allow protocol=UDP localport={MdnsPort}";
                
                var processInfo = new ProcessStartInfo
                {
                    FileName = "netsh",
                    Arguments = command,
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    CreateNoWindow = true,
                    StandardOutputEncoding = Encoding.UTF8
                };

                using (var process = Process.Start(processInfo))
                {
                    if (process != null)
                    {
                        var output = process.StandardOutput.ReadToEnd();
                        var error = process.StandardError.ReadToEnd();
                        process.WaitForExit(3000);
                        if (process.ExitCode == 0)
                        {
                            logCallback?.Invoke($"已添加mDNS防火墙规则（UDP {MdnsPort}端口）。");
                        }
                        else
                        {
                            // 检查是否是因为规则已存在（netsh在某些情况下可能返回非0退出码）
                            var errorMsg = !string.IsNullOrWhiteSpace(error) ? error : output;
                            if (errorMsg.Contains("已存在") || errorMsg.Contains("already exists") || errorMsg.Contains("对象已存在"))
                            {
                                logCallback?.Invoke($"mDNS防火墙规则 '{ruleName}' 已存在。");
                            }
                            else
                            {
                                logCallback?.Invoke($"添加mDNS防火墙规则失败：{errorMsg.Trim()}");
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                logCallback?.Invoke($"添加mDNS防火墙规则时发生错误：{ex.Message}");
            }
        }

        /// <summary>
        /// 检查防火墙规则是否存在
        /// </summary>
        private static bool FirewallRuleExists(string ruleName)
        {
            try
            {
                if (!IsRunningAsAdministrator())
                {
                    return false;
                }

                // 使用 netsh 命令检查防火墙规则是否存在（兼容 Windows 7/10/11）
                var command = $"advfirewall firewall show rule name=\"{ruleName}\"";
                var processInfo = new ProcessStartInfo
                {
                    FileName = "netsh",
                    Arguments = command,
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    CreateNoWindow = true,
                    StandardOutputEncoding = Encoding.UTF8
                };

                using (var process = Process.Start(processInfo))
                {
                    if (process == null)
                    {
                        return false;
                    }

                    var output = process.StandardOutput.ReadToEnd();
                    process.WaitForExit(3000);

                    // 如果规则存在，netsh 会输出规则信息
                    // 如果不存在，通常会输出 "未找到规则" 或类似的错误信息
                    return !string.IsNullOrWhiteSpace(output) && 
                           !output.Contains("未找到") && 
                           !output.Contains("not found") &&
                           output.Contains(ruleName);
                }
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 添加新的打印机服务
        /// </summary>
        public void AddPrinterService(PrinterServiceInfo serviceInfo, int port)
        {
            if (_isRunning && _registeredServices.All(s => s.QueueName != serviceInfo.QueueName))
            {
                var hasBonjour = IsBonjourAvailable();
                RegisterService(serviceInfo, port, _logCallback, hasBonjour);
            }
        }

        /// <summary>
        /// 移除打印机服务
        /// </summary>
        public void RemovePrinterService(string queueName)
        {
            var service = _registeredServices.FirstOrDefault(s => s.QueueName == queueName);
            if (service != null)
            {
                UnregisterService(service);
                _registeredServices.Remove(service);
            }
        }

        /// <summary>
        /// 检查当前是否以管理员权限运行
        /// </summary>
        private static bool IsRunningAsAdministrator()
        {
            try
            {
                using (var identity = System.Security.Principal.WindowsIdentity.GetCurrent())
                {
                    var principal = new System.Security.Principal.WindowsPrincipal(identity);
                    return principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator);
                }
            }
            catch
            {
                return false;
            }
        }

        public void Dispose()
        {
            if (_isDisposed)
            {
                return;
            }

            Stop();
            _isDisposed = true;
        }

        /// <summary>
        /// 打印机服务信息
        /// </summary>
        internal sealed class PrinterServiceInfo
        {
            public string ServiceName { get; set; }
            public string QueueName { get; set; }
            public string PrinterName { get; set; }
        }

        /// <summary>
        /// mDNS服务注册信息
        /// </summary>
        private sealed class MdnsServiceRegistration
        {
            public string ServiceName { get; set; }
            public string QueueName { get; set; }
            public int Port { get; set; }
            public string PrinterName { get; set; }
            public int ProcessId { get; set; } = -1; // dns-sd进程ID（如果使用dns-sd注册）
            public string RegistrationMethod { get; set; } // "dns-sd" 或 "native"
            public string FullServiceName { get; set; } // 完整的服务名称，如 "Printer-Name._ipp._tcp.local"
            public NativeMdnsPublisher NativePublisher { get; set; } // 原生mDNS发布器（如果使用原生协议）
        }
    }
}

